package com.warframe.market.warframe;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tools.HibernateUtils;
import com.tools.StringContent;
import com.warframe.entity.database.WarframeMarketEO;
import com.warframe.entity.database.WarframeMarketKeyWordEO;
import com.warframe.entity.market.warframe.Orders;
import com.warframe.entity.market.warframe.Payload;
import com.warframe.entity.market.warframe.WarframeMarketMO;
import com.warframe.entity.message.Message;
import com.warframe.message.Executor;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

import java.io.IOException;
import java.util.*;

public class WarframeMarket implements Runnable {
    private static String url = "https://api.warframe.market/v1/items/TARGET/orders?include=item";
    private static String sql = "select * from WarframeMarket a where a.item_name_cn like '%TARGET%' order by a.item_name_cn";
    private static String keywordsql = "select * FROM WarframeMarketKeyWord a WHERE a.item_cn LIKE '%TARGET%' ORDER BY a.id";
    private static String psg = "私聊交易指令：[/w 玩家名 hi,i wtb ITEM for 价格 P from warframe.market ]\n请复制[]中内容，并替换玩家名为交易对象名，价格为交易价格，在游戏内聊天框粘贴发送即可开始交易。";
    private String item_cn;
    private String item_en;
    private String item_url;
    private String item_keyword;
    private StringBuilder other = new StringBuilder("您还可以查询以下部件：\n");
    private Boolean otherSwitch = false;
    private Boolean dcSwitch = false;
    private Message message;

    public WarframeMarket(Message message) {
        this.item_cn = message.getMsg();
        this.message = message;
    }

    private void findItemEN() {
        String keyword = item_cn.substring(0, !item_cn.contains(" ") ? item_cn.length() : item_cn.indexOf(" "));
        Session session = HibernateUtils.getSessionFactory().openSession();
        SQLQuery sqlQueryKeyWord = session.createSQLQuery(keywordsql.replace("TARGET", keyword));
        List<WarframeMarketKeyWordEO> warframeMarketKeyWordEOList = sqlQueryKeyWord.addEntity(WarframeMarketKeyWordEO.class).list();
        for (WarframeMarketKeyWordEO eachEO : warframeMarketKeyWordEOList) {
            item_keyword = eachEO.getItemEn();
            break;
        }
        if (item_keyword != null) {
            item_cn = item_cn.replace(keyword, item_keyword);
        }
        item_cn = item_cn.replace(" ", "%");
        SQLQuery sqlQuery = session.createSQLQuery(sql.replace("TARGET", item_cn));
        List<WarframeMarketEO> warframeMarketEOList = sqlQuery.addEntity(WarframeMarketEO.class).list();

        if (warframeMarketEOList.size() > 0) {
            item_en = warframeMarketEOList.get(0).getItemNameEn();
            item_cn = warframeMarketEOList.get(0).getItemNameCn();
            item_url = warframeMarketEOList.get(0).getUrlName();
            if (warframeMarketEOList.size() > 1) {
                otherSwitch = true;
            }
            for (WarframeMarketEO eachEO : warframeMarketEOList) {
                if (null != eachEO.getDucats()) {
                    other.append(eachEO.getItemNameCn() + " DC " + eachEO.getDucats() + " \n");
                    dcSwitch = true;
                } else {
                    other.append(eachEO.getItemNameCn() + " \n");
                }
            }
            if (dcSwitch) {
                other.append("DC表示杜卡德金币（奸商币）价值");
            }
        } else

        {
            Executor.getCQ().logWarning("WarframeMarket NoFoundItem : ", item_cn);
            message.setMsg("未查询到相关物品，请检查物品名后重试");
            if (message.getGroupId() != null) {
                message.setSign(StringContent.SENDGROUP);
            } else {
                message.setSign(StringContent.SENDPERSON);
            }
            message.setFromQQ(message.getFromQQ());
            Executor.getInstance().pushMsg(message);
        }
        session.close();
    }

    public Map<String, Vector<WarframeMarketMO>> getResult() {
        if (item_url != null) {
            CloseableHttpClient httpClient = HttpClients.createDefault(); // 创建httpClient实例
            HttpGet httpGet = new HttpGet(url.replace("TARGET", item_url)); // 创建httpget实例
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
            CloseableHttpResponse response = null; // 执行http get请求
            try {
                response = httpClient.execute(httpGet);
            } catch (IOException e) {
                e.printStackTrace();
            }
            String str = "";
            try {
                str = EntityUtils.toString(response.getEntity());
            } catch (IOException e) {
                e.printStackTrace();
            }

            JSONObject jsonObject;
            try {
                jsonObject = JSONObject.parseObject(str);
            } catch (Exception e) {
                Executor.getCQ().logWarning("WarframeMarket Warning : ", e.getMessage());
                message.setMsg("未查询到相关物品，请检查物品名后重试");
                if (message.getGroupId() != null) {
                    message.setSign(StringContent.SENDGROUP);
                } else {
                    message.setSign(StringContent.SENDPERSON);
                }
                Executor.getInstance().pushMsg(message);
                return null;
            }
            List<Orders> ordersList = null;
            if (jsonObject != null) {
                ordersList = JSON.parseObject(jsonObject.get("payload").toString(), Payload.class).getOrders();
            } else {
                System.out.println();
            }
            Vector<WarframeMarketMO> sellMarketMOs = new Vector<>();
            Vector<WarframeMarketMO> buyMarketMOs = new Vector<>();
            for (Orders eachOrders : ordersList) {
                WarframeMarketMO warframeMarketMO = new WarframeMarketMO();
                warframeMarketMO.setUser(eachOrders.getUser());
                warframeMarketMO.setOrderType(eachOrders.getOrderType());
                warframeMarketMO.setQuantity(eachOrders.getQuantity());
                warframeMarketMO.setModRank(eachOrders.getModRank());
                warframeMarketMO.setPaltinum(eachOrders.getPlatinum());
                if (warframeMarketMO.getUser().getStatus().equals(StringContent.INGAME)) {
                    if (warframeMarketMO.getOrderType().equals(StringContent.SELL)) {
                        sellMarketMOs.add(warframeMarketMO);
                    } else if (warframeMarketMO.getOrderType().equals(StringContent.BUY)) {
                        buyMarketMOs.add(warframeMarketMO);
                    }
                }
            }

            sellMarketMOs.sort(this::compareSell);
            buyMarketMOs.sort(this::compareBuy);

            sellMarketMOs.setSize(5 < sellMarketMOs.size() ? 5 : sellMarketMOs.size());
            buyMarketMOs.setSize(5 < buyMarketMOs.size() ? 5 : buyMarketMOs.size());
            Map<String, Vector<WarframeMarketMO>> result = new HashMap<>();
            result.put(StringContent.BUY, buyMarketMOs);
            result.put(StringContent.SELL, sellMarketMOs);
            return result;
        } else {
            return null;
        }
    }

    private int compareSell(WarframeMarketMO o1, WarframeMarketMO o2) {
        if (o1.getPaltinum() > o2.getPaltinum()) {
            return 1;
        } else if (o1.getPaltinum() < o2.getPaltinum()) {
            return -1;
        }
        return 0;
    }

    private int compareBuy(WarframeMarketMO o1, WarframeMarketMO o2) {
        if (o1.getPaltinum() > o2.getPaltinum()) {
            return -1;
        } else if (o1.getPaltinum() < o2.getPaltinum()) {
            return 1;
        }
        return 0;
    }

    private void explain(Map<String, Vector<WarframeMarketMO>> resultMap) {
        Vector<WarframeMarketMO> sellMarketMOs = resultMap.get(StringContent.SELL);
        Vector<WarframeMarketMO> buyMarketMOs = resultMap.get(StringContent.BUY);
        StringBuilder msgSell = new StringBuilder("指挥官，WM查询结果如下：\n物品名：ITEM 【出售】\n");
        for (WarframeMarketMO eachMO : sellMarketMOs) {
            String str;
            if (eachMO.getModRank() == null) {
                str = eachMO.getPaltinum() + "P 每个,出售 " + eachMO.getQuantity() + " 个 卖家名：[" + eachMO.getUser().getIngameName() + "]\n";
            } else {
                str = eachMO.getPaltinum() + "P 每个,等级 " + eachMO.getModRank() + " ,共售 " + eachMO.getQuantity() + " 个 卖家名：[" + eachMO.getUser().getIngameName() + "]\n";
            }
            msgSell.append(str);
        }
        msgSell.append("回复1查看私聊交易命令\n回复2查看买家\n回复3查看其余部件及杜卡德金币价格");
        Message msgS = new Message(message.getFromQQ(), msgSell.toString().replace("ITEM", item_cn), StringContent.SENDPERSON);
        Executor.getInstance().pushMsg(msgS);
        StringBuilder msgBuy = new StringBuilder("指挥官，WM查询结果如下：\n物品名：ITEM 【求购】\n");
        for (WarframeMarketMO eachMO : buyMarketMOs) {
            String str;
            if (eachMO.getModRank() == null) {
                str = eachMO.getPaltinum() + "P 每个,求购 " + eachMO.getQuantity() + " 个 买家名：[" + eachMO.getUser().getIngameName() + "]\n";
            } else {
                str = eachMO.getPaltinum() + "P 每个,等级 " + eachMO.getModRank() + " ,共收 " + eachMO.getQuantity() + " 个 买家名：[" + eachMO.getUser().getIngameName() + "]\n";
            }
            msgBuy.append(str);
        }
        Map<Integer, Message> layer = new HashMap<>();

        Message msgW = new Message(message.getFromQQ(), psg.replace("ITEM", item_en), StringContent.SENDPERSON);
        layer.put(1, msgW);
        //Executor.getInstance().pushMsg(msgW);
        Message msgB = new Message(message.getFromQQ(), msgBuy.toString().replace("ITEM", item_cn), StringContent.SENDPERSON);
        layer.put(2, msgB);
        //Executor.getInstance().pushMsg(msgB);
        if (otherSwitch) {
            Message msgO = new Message(message.getFromQQ(), other.toString(), StringContent.SENDPERSON);
            layer.put(3, msgO);
            //Executor.getInstance().pushMsg(msgO);
        }
        StringContent.MESSAGELAYER.put(message.getFromQQ(), layer);
    }

    @Override
    public void run() {
        findItemEN();
        Map<String, Vector<WarframeMarketMO>> resultMap = getResult();
        if (resultMap != null) {
            explain(resultMap);
        }
    }
}
